﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once

#include "GcmpDevService.h"
#include <unordered_set>
#ifdef _WINDOWS
#include <guiddef.h>
#include <objbase.h>
typedef GUID Guid;
#else
#include <cstring>
#include <cstdint>

#pragma pack (push)
#pragma pack (1)
struct Guid
{
    uint32_t  Data1;
    uint16_t  Data2;
    uint16_t  Data3;
    uint8_t   Data4[8];
};
#pragma pack (pop)
inline int operator == (const Guid &left, const Guid &right)
{
    return !memcmp(&left, &right, sizeof(Guid));
}

#define TRUE 1
#define S_OK                  (0L)
#define S_FALSE               (1L)
#define E_OUTOFMEMORY         (0x8007000EL)
#endif
bool GCMP_DEV_SERVICE_EXPORT operator < (const Guid &left, const Guid &right);

namespace gcmp
{
    /// \brief Guid哈希仿函数
    struct GCMP_DEV_SERVICE_EXPORT GuidHasher
    {
        std::size_t operator()(const Guid& key) const
        {
            return (key.Data1 ^ ((key.Data2 << 0x10) | key.Data3)) ^ ((key.Data4[2] << 0x18) | key.Data4[7]);
        }
    };

    /// \brief Guid相等仿函数
    struct GCMP_DEV_SERVICE_EXPORT GuidEqual
    {
        bool operator()(const Guid & lhs, const Guid & rhs) const
        {
            return 1 == (lhs == rhs);
        }
    };

    /// \brief Guid比较仿函数
    struct GCMP_DEV_SERVICE_EXPORT GuidComparer
    {
        bool operator()(const Guid& left, const Guid& right) const
        {
            return left < right;
        }
    };

    typedef std::unordered_set<Guid, GuidHasher, GuidEqual> GuidUnorderedSet;

    /// \brief Guid工具类
    class GCMP_DEV_SERVICE_EXPORT GuidUtils
    {
    public:
        /// \brief 获取不合法的Guid
        static const Guid& GetInvalid();

        /// \brief 将Guid转换成字符串
        ///
        /// 如果使用紧凑模式，返回"0123456789ABCDEF0123456789ABCDEF"这样的格式；
        /// 否则返回"{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}"这样的格式，是否有花括号取决于withCurlyBraces参数。
        ///
        /// \param guid Guid对象
        /// \param compactMode 是否使用紧凑模式，默认是false
        /// \param withCurlyBraces 首尾是否有花括号
        /// \return std::wstring 字符串
        static std::wstring ToString(const Guid &guid, bool compactMode = false, bool withCurlyBraces = true);

        /// \brief 通过字符串创建Guid
        ///
        /// 将符合"{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}"这样的格式的字符串转换成Guid；不符合格式的返回Invalid。
        ///
        /// \param str 符合格式的Guid字符串
        /// \return Guid 创建的Guid
        static Guid FromString(const std::wstring &str);

        /// \brief 创建Guid
        static Guid Generate();

        /// \brief 判断是否是合法的Guid
        /// \param guid 输入的guid
        /// \return bool 合法返回true；不合法返回false
        static bool IsValid(const Guid& guid);

    private:
        static Guid s_invalidGuid;
    };
}
